#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author:zhuyan
@file: knn.py
@time: 2018/10/08
"""
import sys
from numpy import *
import operator


class KnnDemo:

    def create_dataset(self):
        group = array([[1.0, 2.0], [1.2, 0.1], [0.1, 1.4], [0.3, 3.5]])
        # 二维数组：4行一列
        print(group.shape)
        labels = ['A', 'A', 'B', 'B']
        return group, labels

    def classfiy_cnn(self, input, data_set, label, k):
        dataSize = data_set.shape[0]


        #### 计算欧式距离
        print(tile(input, (dataSize, 1)))
        # 使用广播方式进行数组复制，复制4行，列保持1
        diff = tile(input, (dataSize, 1)) - dataSet
        # 数组相减，d2-a2,d1-a1
        print(type(diff))
        print(diff)
        # 求次方(d2-a2)的平方，d1-a1的平方
        sqdiff = diff ** 2
        # 平方相加，行向量相加
        squareDist = sum(sqdiff, axis=1)  ###行向量分别相加，从而得到新的一个行向量
        # 再开方
        dist = squareDist ** 0.5

        print(type(dist))
        print(dist)

        ##对距离进行排序，返回对应的下标，用于获取前n个分类
        sortedDistIndex = argsort(dist)  ##argsort()根据元素的值从大到小对元素进行排序，返回下标

        classCount = {}
        for i in range(k):
            voteLabel = label[sortedDistIndex[i]]
            ###对选取的K个样本所属的类别个数进行统计
            # 查找是否有这个key，有返回相应值，否则返回0
            classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
        ### 选取出现的类别次数最多的类别
        maxCount = 0
        for key, value in classCount.items():
            if value > maxCount:
                maxCount = value
                classes = key
        print(maxCount)

        return classes


if __name__ == '__main__':
    demo = KnnDemo()
    dataSet, labels = demo.create_dataset()
    input = array([1.1, 0.3])
    K = 3
    output = demo.classfiy_cnn(input, dataSet, labels, K)
    print("测试数据为:", input, "分类结果为：", output)